package com.youseeseeyou.blog.web.controller.admin;

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.concurrent.TimeUnit;

/**
 * Created by lanjingyou on 2021/9/30.
 */
@Controller
@RequestMapping("/admin/redis")
@Slf4j
public class RedissonDemo {
    @Autowired
    private RedissonClient redissonClient;

    @GetMapping(value ="/test",produces = "application/json;charset=UTF-8")
    @ResponseBody
    public String test(){
        String msg = "";
        String key = "aa:bb:cc:01";
        RLock rLock =redissonClient.getLock(key);
        // 尝试加锁，最多等待1秒，上锁以后10秒自动解锁<br>// 没有Watch Dog ，10s后自动释放
        try {
            boolean res = rLock.tryLock(1,10, TimeUnit.SECONDS);
            if (res){
                msg = "获得锁==========="+res;
                log.info("获得锁==========="+res);
            }else {
                msg = "没有获得锁==========="+res;
                log.info("没有获得锁==========="+res);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally{
            rLock.unlock();
        }
        return msg ;
    }

    private void redissonDoc() throws InterruptedException {
        //1. 普通的可重入锁
        RLock lock = redissonClient.getLock("generalLock");

        // 拿锁失败时会不停的重试
        // 具有Watch Dog 自动延期机制 默认续30s 每隔30/3=10 秒续到30s
        lock.lock();

        // 尝试拿锁10s后停止重试,返回false
        // 具有Watch Dog 自动延期机制 默认续30s
        boolean res1 = lock.tryLock(10, TimeUnit.SECONDS);

        // 拿锁失败时会不停的重试
        // 没有Watch Dog ，10s后自动释放
        lock.lock(10, TimeUnit.SECONDS);

        // 尝试拿锁100s后停止重试,返回false
        // 没有Watch Dog ，10s后自动释放
        boolean res2 = lock.tryLock(100, 10, TimeUnit.SECONDS);

        //2. 公平锁 保证 Redisson 客户端线程将以其请求的顺序获得锁
        RLock fairLock = redissonClient.getFairLock("fairLock");

        //3. 读写锁 没错与JDK中ReentrantLock的读写锁效果一样
        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("readWriteLock");
        readWriteLock.readLock().lock();
        readWriteLock.writeLock().lock();
    }
}
